from flightanalysis.data.p23 import create_p23
from flightanalysis.schedule.definition import SchedDef
from flightanalysis.schedule import Schedule, Manoeuvre
from flightdata import Flight
from flightanalysis import State, Box
from flightplotting import plotsec, plotdtw
from flightanalysis.criteria.combination import Combination
import numpy as np
np.set_printoptions(suppress=True)
import plotly
plotly.offline.init_notebook_mode()
from flightanalysis import Line, Loop, Spin, StallTurn, Snap
from geometry import Transformation
Parse a flight log, rotate it to the flightline and cutoff the takeoff and landing.
#parse a flight, cutoff takeoff and landing
flown = State.from_flight(
Flight.from_csv("examples/data/p23_example.csv").flying_only(),
Box.from_f3a_zone("examples/data/p23_box.f3a")
)[39:405]
Create a Schedule Definition using the create_p23 generator function. Use this to create a P23 Schedule and template State information. This is done at the average depth of the flown data and in the same direction.
wind=np.sign(flown[0].vel.x[0])
p23_def = create_p23(wind) # wind direction used here because it makes the M go out and the fighter turn come back again,
p23, template = p23_def.create_template(flown.pos.y.mean(), wind)
Align the template to the flight data.
dist, aligned = State.align(flown, template, 10)
Update the schedule to match the flight
intended = p23.match_intention(template[0].transform, aligned)
Create a new template then repeat the alignment, this time without mirroring roll and yaw directions. The resulting alignment is better than the first as it picks up rebound rolls and the axis rates of the template match the flown data.
intended_template = intended.create_template(Transformation(
aligned[0].pos,
aligned[0].att.closest_principal()
))
dist, aligned = State.align(flown, intended_template, 10, False)
from ipywidgets import widgets, interactive
import plotly.graph_objects as go
def dtwman(man):
man=man-1
fig = plotdtw(p23[man].get_data(aligned), p23[man].all_elements.to_list())
display(go.FigureWidget(data=fig.data, layout=fig.layout))
widgets.interactive(dtwman, man=widgets.IntSlider(min=1, max=17, value=1, step=1))
Correct the intended inter element parameters to make a corrected shcedule and template
p23_def.update_defaults(intended)
corrected, corrected_template = p23_def.create_template(flown.pos.y.mean(), wind)
The intended template just follows the roll directions used in the flight. The corrected template corrects the roll directions if they do not fit a valid option defined in the manoeuvre parameters. We want the intended template to have these corrected roll directions.
This is commented for now as not working properly so we just assume that the roll directions flown correspond with a valid option.
#intended = intended.copy_directions(corrected)
#intended_template = intended.create_template(Transformation(
# aligned[0].pos,
# aligned[0].att.closest_principal()
#))
Now we have aligned and intended templates we can score the manoeuvres.
from json import dumps
from ipywidgets import widgets, interactive
from IPython.display import display, HTML
import plotly.graph_objects as go
import numpy as np
import pandas as pd
def scoreman(man, fl, intent, corr, inter, intra, el):
man=intended[man-1]
el=man.elements[el-1]
transform = man.get_data(aligned)[0].transform
results = p23_def[man.uid].mps.collect(man)
intra_results = man.analyse(
man.get_data(aligned),
man.get_data(intended_template)
)
interdg=results.downgrade()
intradg = intra_results.downgrade()
score = 10 - interdg - intradg
display(widgets.HTML(f"10 - {intra_results.downgrade_list()} (intra) - {interdg} (inter) = <h1>{man.uid}: {score}</h1>"))
fig=None
if intent:
fig = plotsec(
man.get_data(intended_template).relocate(transform.pos),
fig=fig
)
if fl:
fig = plotsec(man.get_data(aligned), fig=fig)
if corr:
fig = plotsec(
p23_def[man.uid].create(transform).create_template(Transformation(
transform.pos,
man.get_data(corrected_template)[0].att
)),
fig=fig
)
if fig:
display(go.FigureWidget(fig.data, fig.layout))
if inter:
display("Inter Element Summary")
display(results.downgrade_df())
if intra:
display(intra_results[el.uid].results.downgrade_df())
man=widgets.IntSlider(min=1, max=17, value=1, step=1, description="manoeuvre")
fl = widgets.Checkbox(True, description="Plot Flown")
intent = widgets.Checkbox(False, description="Plot Intended")
corr = widgets.Checkbox(False, description="Plot Corrected")
inter = widgets.Checkbox(False, description="Inter Summary")
intra = widgets.Checkbox(False, description="Intra Summary")
el=widgets.IntSlider(min=1, max=20, value=1, step=1, description="Element")
controls = widgets.HBox(children=[man, el], )
controls1 = widgets.HBox(children=[fl, intent, corr, inter, intra], )
results = widgets.interactive_output(scoreman, dict(man=man, fl=fl, intent=intent, corr=corr, inter=inter, intra=intra, el=el))
widgets.VBox([controls, controls1, results])